package com.sky.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.ProductConstant;
import com.sky.domain.PmsAttr;
import com.sky.domain.PmsAttrAttrgroupRelation;
import com.sky.domain.PmsAttrGroup;
import com.sky.domain.PmsCategory;
import com.sky.mapper.PmsAttrAttrgroupRelationMapper;
import com.sky.service.PmsAttrGroupService;
import com.sky.service.PmsAttrService;
import com.sky.mapper.PmsAttrMapper;
import com.sky.service.PmsCategoryService;
import com.sky.utils.PageUtils;
import com.sky.utils.StringUtils;
import com.sky.vo.param.PmsAttrVO;
import com.sky.vo.request.PmsAttrRequestVO;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【pms_attr(商品属性)】的数据库操作Service实现
* @createDate 2024-06-30 16:46:42
*/
@Service
public class PmsAttrServiceImpl extends ServiceImpl<PmsAttrMapper, PmsAttr> implements PmsAttrService{

    @Resource
    private PmsAttrAttrgroupRelationMapper pmsAttrAttrgroupRelationMapper;
    @Resource
    private PmsCategoryService pmsCategoryService;
    @Resource
    private PmsAttrGroupService pmsAttrGroupService;

    /**
     * 分页查询商品属性
     * @param vo
     * @return
     */
    @Override
    public PageUtils queryPage(PmsAttrVO vo) {
        // 属性类型
        String type = vo.getType();
        if (StringUtils.isNotEmpty(type) && ProductConstant.AttrEnum.ATTR_TYPE_BASE.getDesc().equals(type)){
            vo.setAttrType(ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        } else {
            vo.setAttrType(ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        }

        PageUtils pageUtils = PageUtils.selectPage(this.baseMapper, vo, PmsAttr.class);

        List<PmsAttr> records = pageUtils.getRecords();

        List<PmsAttrRequestVO> list = records.stream().map(pmsAttrEntity -> {
            PmsAttrRequestVO requestVO = new PmsAttrRequestVO();
            BeanUtils.copyProperties(pmsAttrEntity, requestVO);

            if (StringUtils.isNotEmpty(pmsAttrEntity.getCatalogId())){
                PmsCategory category = pmsCategoryService.getById(pmsAttrEntity.getCatalogId());
                requestVO.setCatalogName(category.getName());
            }

            PmsAttrAttrgroupRelation pmsAttrAttrgroupRelation = pmsAttrAttrgroupRelationMapper.selectOne(new LambdaUpdateWrapper<PmsAttrAttrgroupRelation>()
                    .eq(PmsAttrAttrgroupRelation::getAttrId, pmsAttrEntity.getAttrId()));
            if (pmsAttrAttrgroupRelation != null){
                PmsAttrGroup pmsAttrGroup = pmsAttrGroupService.getById(pmsAttrAttrgroupRelation.getAttrGroupId());
                if (pmsAttrGroup != null){
                    requestVO.setAttrGroupName(pmsAttrGroup.getAttrGroupName());
                }
            }

            return requestVO;
        }).collect(Collectors.toList());

        pageUtils.setRecords(list);

        return pageUtils;
    }

    /**
     * 根据id查询商品属性
     *
     * @param attrId 商品属性id
     * @return 商品属性
     */
    @Override
    public PmsAttrRequestVO getPmsAttr(Long attrId) {
        PmsAttr pmsAttr = baseMapper.selectById(attrId);

        PmsAttrRequestVO vo = new PmsAttrRequestVO();
        BeanUtils.copyProperties(pmsAttr, vo);

        List<Long> path = pmsCategoryService.getPath(pmsAttr.getCatalogId(), new ArrayList<>());
        vo.setCategoryPath(path);

        if (StringUtils.isNotEmpty(vo.getAttrId())){
            PmsAttrAttrgroupRelation pmsAttrAttrgroupRelation = pmsAttrAttrgroupRelationMapper.selectOne(new LambdaUpdateWrapper<PmsAttrAttrgroupRelation>()
                    .eq(PmsAttrAttrgroupRelation::getAttrId, vo.getAttrId()));
            if (pmsAttrAttrgroupRelation != null){
                PmsAttrGroup pmsAttrGroup = pmsAttrGroupService.getById(pmsAttrAttrgroupRelation.getAttrGroupId());
                if (pmsAttrGroup != null){
                    vo.setAttrGroupId(pmsAttrGroup.getAttrGroupId());
                }
            }
        }
        return vo;
    }

    /**
     * 新增商品属性
     *
     * @param pmsAttrVO 商品属性
     * @return 是否新增成功
     */
    @Override
    public boolean savePmsAttr(PmsAttrVO pmsAttrVO) {
        baseMapper.insert(pmsAttrVO);

        Long attrGroupId = pmsAttrVO.getAttrGroupId();
        if (StringUtils.isNotEmpty(attrGroupId) || ProductConstant.AttrEnum.ATTR_TYPE_BASE.getDesc().equals(pmsAttrVO.getType())){
            PmsAttrAttrgroupRelation pmsAttrAttrgroupRelation = new PmsAttrAttrgroupRelation();
            pmsAttrAttrgroupRelation.setAttrGroupId(attrGroupId);
            pmsAttrAttrgroupRelation.setAttrId(pmsAttrVO.getAttrId());
            pmsAttrAttrgroupRelationMapper.insert(pmsAttrAttrgroupRelation);
        }

        return true;
    }


    /**
     * 更新商品属性信息，并根据属性组ID和属性类型决定是否插入或更新属性与属性组的关系。
     *
     * @param pmsAttrVO 商品属性VO对象，包含属性的详细信息。
     * @return 更新操作是否成功的布尔值，始终返回true，表示更新操作已执行。
     */
    @Override
    public boolean updatePmsAttr(PmsAttrVO pmsAttrVO) {
        // 通过BaseMapper更新属性信息
        baseMapper.updateById(pmsAttrVO);

        // 获取属性组ID
        Long attrGroupId = pmsAttrVO.getAttrGroupId();

        // 查询当前属性是否已关联属性组
        PmsAttrAttrgroupRelation pmsAttrAttrgroupRelation = pmsAttrAttrgroupRelationMapper.selectOne(new LambdaUpdateWrapper<PmsAttrAttrgroupRelation>()
                .eq(PmsAttrAttrgroupRelation::getAttrId, pmsAttrVO.getAttrId()));

        if (pmsAttrAttrgroupRelation == null){
            // 如果属性尚未关联属性组，且属性组ID不为空或属性类型为基础属性，则插入属性与属性组的关系
            if (StringUtils.isNotEmpty(attrGroupId) || ProductConstant.AttrEnum.ATTR_TYPE_BASE.getDesc().equals(pmsAttrVO.getType())){
                PmsAttrAttrgroupRelation relation = new PmsAttrAttrgroupRelation();
                relation.setAttrGroupId(attrGroupId);
                relation.setAttrId(pmsAttrVO.getAttrId());
                pmsAttrAttrgroupRelationMapper.insert(relation);
            }
        } else {
            // 如果属性已关联属性组，判断是否需要更新或删除关系
            if (StringUtils.isNotEmpty(attrGroupId) || ProductConstant.AttrEnum.ATTR_TYPE_BASE.getDesc().equals(pmsAttrVO.getType())){
                // 如果属性组ID不为空或属性类型为基础属性，更新属性与属性组的关系
                pmsAttrAttrgroupRelationMapper.update(null,new LambdaUpdateWrapper<PmsAttrAttrgroupRelation>()
                        .eq(PmsAttrAttrgroupRelation::getAttrId, pmsAttrVO.getAttrId())
                        .set(PmsAttrAttrgroupRelation::getAttrGroupId, attrGroupId));
            } else {
                // 如果既不满足属性组ID条件也不满足属性类型条件，则删除属性与属性组的关系
                pmsAttrAttrgroupRelationMapper.delete(new LambdaUpdateWrapper<PmsAttrAttrgroupRelation>()
                        .eq(PmsAttrAttrgroupRelation::getAttrId, pmsAttrVO.getAttrId()));
            }
        }

        // 更新操作始终返回成功
        return true;
    }

    /**
     * 根据属性分组id查询属性
     * @param attrGroupId 属性分组id
     * @return 属性
     */
    @Override
    public List<PmsAttrRequestVO> attrGroupRelation(Long attrGroupId) {
        List<PmsAttrAttrgroupRelation> relations = pmsAttrAttrgroupRelationMapper.selectList(new LambdaUpdateWrapper<PmsAttrAttrgroupRelation>()
                .eq(PmsAttrAttrgroupRelation::getAttrGroupId, attrGroupId));
        Set<Long> set = relations.stream().map(PmsAttrAttrgroupRelation::getAttrId).collect(Collectors.toSet());
        List<PmsAttr> pmsAttrs = baseMapper.selectBatchIds(set);
        List<PmsAttrRequestVO> voList = pmsAttrs.stream().map(pmsAttr -> {
            PmsAttrRequestVO vo = new PmsAttrRequestVO();
            BeanUtils.copyProperties(pmsAttr, vo);
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     * 分页查询商品属性
     * 1、一个分类有多个分组，一个分组只能有一个分类，一对多的关系
     * 2、一个分组有多个属性，一个属性只能有一个分组，一对多的关系
     * 这里需要查询的是当前分组的分类下面的所有未关联分组的属性，步骤如下：
     *  1）通过分组id查询分组信息，获取该分组所属分类
     *  2）通过分类id查询分类下面的所有分组
     *  3）查询分类下面的所有属性，即所有分组的所有属性
     *  4）在属性表中查询 1、该分类下面、2、没有关联分组、3、类型为“基本属性” 的属性
     * @param vo 查询条件
     * @return 商品属性
     */
    @Override
    public PageUtils pageNoGroupRelation(PmsAttrVO vo) {
        PmsAttrGroup pmsAttrGroup = pmsAttrGroupService.getById(vo.getAttrGroupId());
        Long catelogId = pmsAttrGroup.getCatalogId();

        // 查询该分类下面的其他分组
        List<PmsAttrGroup> groupList = pmsAttrGroupService.list(new LambdaQueryWrapper<PmsAttrGroup>()
                .eq(PmsAttrGroup::getCatalogId, catelogId));

        List<Long> list = groupList.stream().map(PmsAttrGroup::getAttrGroupId).collect(Collectors.toList());
        // 查询所有分组下的所有属性（即该分类下面的所有属性）
        List<PmsAttrAttrgroupRelation> pmsAttrAttrgroupRelations = pmsAttrAttrgroupRelationMapper.selectList(new LambdaQueryWrapper<PmsAttrAttrgroupRelation>()
                .in(PmsAttrAttrgroupRelation::getAttrGroupId, list));

        if (StringUtils.isEmpty(pmsAttrAttrgroupRelations)){
            return null;
        }

        // 该分类下面所有属性id集合
        List<Long> attrIds = pmsAttrAttrgroupRelations.stream().filter(data -> StringUtils.isNotEmpty(data.getAttrId())).map(PmsAttrAttrgroupRelation::getAttrId).collect(Collectors.toList());

        LambdaQueryWrapper<PmsAttr> queryWrapper = new LambdaQueryWrapper<PmsAttr>()
                .eq(PmsAttr::getCatalogId, catelogId)
                .eq(PmsAttr::getAttrType, ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode())
                .notIn(PmsAttr::getAttrId, attrIds);
        if (StringUtils.isNotEmpty(vo.getAttrName())){
            queryWrapper.like(PmsAttr::getAttrName, vo.getAttrName());
        }

        PageUtils pageUtils = PageUtils.selectPage(baseMapper, queryWrapper);
        return pageUtils;
    }
}




